home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
fish
/
676-700
/
681
/
term
/
source.lha
/
Console.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-09
|
27KB
|
1,659 lines
/*
** $Id: Console.c,v 1.5 92/05/01 12:52:03 olsen Sta Locker: olsen $
** $Revision: 1.5 $
** $Date: 92/05/01 12:52:03 $
**
** High-level console control routines
**
** Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
** All Rights Reserved
*/
#include "termGlobal.h"
/* Use a simple address trick instead of the predefined
* address in amiga.lib.
*/
#ifndef custom
#define custom (*(struct Custom *)0xDFF000)
#endif /* custom */
/* The characters to abort parsing a control sequence. */
STATIC BYTE AbortTable[256] =
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
/* StripSequence():
*
* Strips a string from ESC and CSI introduced control
* sequences.
*/
STATIC LONG __regargs
StripSequence(UBYTE *Src,UBYTE *Dst,LONG Length)
{
STATIC BYTE HasESC = FALSE,HasCSI = FALSE;
LONG Size = 0;
while(Length--)
{
if(*Src == 24 || *Src == 26)
{
HasESC = HasCSI = FALSE;
Src++;
continue;
}
if(*Src == '\r')
{
Src++;
continue;
}
if(HasESC)
{
if(*Src == '[')
{
HasESC = FALSE;
HasCSI = TRUE;
}
else
{
if(*Src >= '0')
HasESC = FALSE;
}
Src++;
continue;
}
if(HasCSI)
{
if(*Src >= '@')
HasCSI = FALSE;
Src++;
continue;
}
switch(*Src)
{
case ESC: HasESC = TRUE;
Src++;
continue;
case CSI: HasCSI = TRUE;
Src++;
continue;
default: if(!ValidTab[*Src])
{
Src++;
continue;
}
break;
}
*Dst++ = *Src++;
Size++;
}
return(Size);
}
/* CaptureToFile(APTR Buffer,LONG Size):
*
* Send data to the capture file.
*/
VOID __regargs
CaptureToFile(APTR Buffer,LONG Size)
{
if(FileCapture && Size)
{
struct MenuItem *SomeItem;
if(BufferWrite(FileCapture,Buffer,Size) != Size)
{
BlockWindows();
/* We had an error writing to the file. */
switch(MyEasyRequest(NULL,LocaleString(MSG_CONSOLE_ERROR_WRITING_TO_CAPTURE_FILE_TXT),LocaleString(MSG_CONSOLE_IGNORE_DISCARD_CLOSE_TXT),CaptureName))
{
case 0: break;
case 1: BufferClose(FileCapture);
DeleteFile(CaptureName);
if(SomeItem = FindThisItem(MEN_CAPTUREDISK))
SomeItem -> Flags &= ~CHECKED;
FileCapture = NULL;
break;
case 2: BufferClose(FileCapture);
if(SomeItem = FindThisItem(MEN_CAPTUREDISK))
SomeItem -> Flags &= ~CHECKED;
FileCapture = NULL;
if(!GetFileSize(CaptureName))
DeleteFile(CaptureName);
else
SetProtection(CaptureName,FIBF_EXECUTE);
break;
}
ReleaseWindows();
}
}
}
/* Capture(APTR Buffer,LONG Size):
*
* Send the buffer contents to the display/disk capture.
*/
VOID __regargs
Capture(APTR Buffer,LONG Size)
{
struct MenuItem *SomeItem;
/* Send the filtered data to the capture file. */
if(Config . CaptureFilter)
CaptureToFile(Buffer,Size);
/* Store data in the log book. */
if(!BufferFrozen)
StoreBuffer(Buffer,Size);
/* Send the buffer to the printer. */
if(PrinterCapture && Size)
{
if(!FWrite(PrinterCapture,Buffer,Size,1))
{
BlockWindows();
if(!MyEasyRequest(Window,LocaleString(MSG_CONSOLE_ERROR_WRITING_TO_PRINTER_TXT),LocaleString(MSG_CONSOLE_IGNORE_CLOSE_PRINTER_TXT)))
{
Close(PrinterCapture);
if(SomeItem = FindThisItem(MEN_CAPTUREPRINTER))
SomeItem -> Flags &= ~CHECKED;
PrinterCapture = NULL;
}
ReleaseWindows();
}
}
}
/* ClosePrinterCapture(BYTE Force):
*
* Closes printer capture file.
*/
VOID
ClosePrinterCapture(BYTE Force)
{
struct MenuItem *Item = FindThisItem(MEN_CAPTUREPRINTER);
if(PrinterCapture)
{
if(ControllerActive && StandardPrinterCapture && !Force)
FPrintf(PrinterCapture,LocaleString(MSG_CONSOLE_TERMINAL_TRANSCRIPT_ENDING_TXT));
if(Force)
{
Close(PrinterCapture);
Item -> Flags &= ~CHECKED;
PrinterCapture = NULL;
StandardPrinterCapture = FALSE;
}
}
ControllerActive = FALSE;
}
/* OpenPrinterCapture(BYTE Controller):
*
* Opens printer capture file.
*/
BYTE
OpenPrinterCapture(BYTE Controller)
{
if(PrinterCapture)
{
if(Controller && !ControllerActive)
{
ControllerActive = TRUE;
FPrintf(PrinterCapture,LocaleString(MSG_CONSOLE_TERMINAL_TRANSCRIPT_FOLLOWS_TXT));
}
return(TRUE);
}
else
{
struct MenuItem *Item = FindThisItem(MEN_CAPTUREPRINTER);
if(PrinterCapture = Open("PRT:",MODE_NEWFILE))
Item -> Flags |= CHECKED;
else
{
Item -> Flags &= ~CHECKED;
BlockWindows();
MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_ERROR_OPENING_PRINTER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
ReleaseWindows();
}
if(Controller)
{
ControllerActive = TRUE;
StandardPrinterCapture = FALSE;
}
else
{
StandardPrinterCapture = FALSE;
if(ControllerActive)
FPrintf(PrinterCapture,LocaleString(MSG_CONSOLE_USER_TERMINAL_TRANSCRIPT_FOLLOWS_TXT));
}
if(PrinterCapture)
return(TRUE);
else
return(FALSE);
}
}
/* PrintRegion(WORD Top,WORD Bottom):
*
* Print the contents of a screen region.
*/
VOID
PrintRegion(WORD Top,WORD Bottom)
{
BPTR SomeFile;
WORD i,j;
UBYTE *Buffer;
if(PrinterCapture)
{
if(!FPrintf(PrinterCapture,LocaleString(MSG_CONSOLE_SCREEN_PRINTOUT_FOLLOWS_TXT)))
{
MyEasyRequest(Window,LocaleString(MSG_CONSOLE_ERROR_WRITING_TO_PRINTER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
return;
}
SomeFile = PrinterCapture;
}
else
{
if(!(SomeFile = Open("PRT:",MODE_NEWFILE)))
{
MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_PRINTER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
return;
}
}
for(i = Top ; i < Bottom ; i++)
{
Buffer = &Raster[i * RasterWidth];
j = LastColumn;
while(j >= 0 && Buffer[j] == ' ')
j--;
if(j >= 0)
{
if(!FWrite(SomeFile,Buffer,j + 1,1))
break;
}
if(!FWrite(SomeFile,"\n",1,1))
break;
}
if(PrinterCapture)
FPrintf(PrinterCapture,LocaleString(MSG_CONSOLE_SCREEN_PRINTOUT_ENDING_TXT));
else
Close(SomeFile);
}
/* HandleCursor(UBYTE Char):
*
* This routine handles the somewhat strange behaviour of
* an assorted set of keys in VT100 applications mode.
*/
BYTE __regargs
HandleCursor(UBYTE Char)
{
STATIC struct
{
UBYTE Char;
UBYTE *VanillaString;
UBYTE *ApplicationString;
} Table[18] =
{
CUP, "\033[A", "\033OA",
CDN, "\033[B", "\033OB",
CFW, "\033[C", "\033OC",
CBK, "\033[D", "\033OD",
'0', "0", "\033Op",
'1', "1", "\033Oq",
'2', "2", "\033Or",
'3', "3", "\033Os",
'4', "4", "\033Ot",
'5', "5", "\033Ou",
'6', "6", "\033Ov",
'7', "7", "\033Ow",
'8', "8", "\033Ox",
'9', "9", "\033Oy",
'-', "-", "\033Om",
'*', "*", "\033Ol",
'.', ".", "\033On",
'\r', "\r", "\033OM"
};
BYTE i;
/* Look for the cursor keys first. */
for(i = 0 ; i < 4 ; i++)
{
if(Table[i] . Char == Char)
{
if(Config . CursorApp)
SerWrite(Table[i] . ApplicationString,strlen(Table[i] . ApplicationString));
else
SerWrite(Table[i] . VanillaString,strlen(Table[i] . VanillaString));
return(TRUE);
}
}
/* Then take a look at the numeric pad. */
for(i = 4 ; i < 18 ; i++)
{
if(Table[i] . Char == Char)
{
if(Config . NumApp)
SerWrite(Table[i] . ApplicationString,strlen(Table[i] . ApplicationString));
else
{
if(i == 17)
{
switch(Config . SendCR)
{
case CR_IGNORE: break;
case CR_ASCR: SerWrite("\r",1);
break;
case CR_ASCRLF: SerWrite("\r\n",2);
break;
}
}
else
SerWrite(Table[i] . VanillaString,strlen(Table[i] . VanillaString));
}
return(TRUE);
}
}
return(FALSE);
}
/* DoBackspace():
*
* Special function: perform backspace.
*/
VOID
DoBackspace()
{
Capture("\b",1);
if(CursorX)
{
ClearCursor();
CursorX--;
/* If destructive, shift the remaining line
* one character to the right.
*/
if(Config . DestructiveBackspace)
{
WORD DeltaX,MinX;
BackupRender();
SetBPen(RPort,0);
RasterEraseCharacters(1);
if(Config . FontScale == SCALE_NORMAL)
{
if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
{
DeltaX = 8;
MinX = CursorX << 3;
}
else
{
DeltaX = 4;
MinX = CursorX << 2;
}
}
else
{
if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
{
DeltaX = 4;
MinX = CursorX << 2;
}
else
{
DeltaX = 8;
MinX = CursorX << 3;
}
}
ScrollLineEraseCharacters(1);
ScrollLineRaster(RPort,DeltaX,0,MinX,CursorY * 8,LastPixel,(CursorY + 1) * 8 - 1);
BackupRender();
}
SetCursor();
}
}
/* DoSomeBeep():
*
* The real interface to the beep routine.
*/
VOID
DoSomeBeep()
{
/* Handle the visual part. */
if(Config . VisibleBell || Config . SystemBeep)
{
if(StatusProcess)
Signal(StatusProcess,SIGBREAKF_CTRL_D);
}
/* Let it beep. */
if(Config . AudibleBell)
Beep();
/* Capture the bell. */
if(!Config . CaptureFilter)
Capture("\a",1);
}
/* DoLF():
*
* Special function: perform line feed.
*/
VOID
DoLF()
{
if(Config . ReceiveLF == LF_ASLFCR)
{
ClearCursor();
CursorX = 0;
DownLine();
SetCursor();
Capture("\n",1);
}
else
{
if(Config . ReceiveLF == LF_ASLF)
{
ClearCursor();
DownLine();
SetCursor();
}
}
}
/* DoShiftIn():
*
* Special function: Shift into graphics mode
*/
VOID
DoShiftIn()
{
if(CharMode[1] == TABLE_GFX && GFX)
CurrentFont = GFX;
if(CharMode[1] == TABLE_ASCII)
{
if(Config . Font == FONT_IBM && IBM)
CurrentFont = IBM;
else
CurrentFont = Topaz;
}
SetFont(RPort,CurrentFont);
Charset = 1;
}
/* DoShiftOut():
*
* Special function: Shift out of graphics mode
*/
VOID
DoShiftOut()
{
if(CharMode[0] == TABLE_GFX && GFX)
CurrentFont = GFX;
if(CharMode[0] == TABLE_ASCII)
{
if(Config . Font == FONT_IBM && IBM)
CurrentFont = IBM;
else
CurrentFont = Topaz;
}
SetFont(RPort,CurrentFont);
Charset = 0;
}
/* DoIgnore():
*
* Special function: don't do anything.
*/
VOID
DoIgnore()
{
}
/* DoCR_LF():
*
* Special function: perform carriage return and line feed.
*/
VOID
DoCR_LF()
{
ClearCursor();
CursorX = 0;
DownLine();
SetCursor();
Capture("\n",1);
}
/* DoFF():
*
* Special function: perform form feed.
*/
VOID
DoFF()
{
if(Config . NewLine)
{
CursorX = 0;
DoCR_LF();
}
else
{
EraseScreen("2");
ClearCursor();
CursorX = CursorY = 0;
SetCursor();
Capture("\n",1);
}
}
/* DoLF_FF_VT():
*
* Special function: handle line feed, form feed and vertical
* tab.
*/
VOID
DoLF_FF_VT()
{
if(Config . NewLine)
DoCR_LF();
else
DoLF();
}
/* DoCR():
*
* Special function: handle carriage return.
*/
VOID
DoCR()
{
if(Config . NewLine || Config . ReceiveCR == CR_ASCRLF)
DoCR_LF();
else
{
if(Config . ReceiveCR == CR_ASCR)
{
ClearCursor();
CursorX = 0;
SetCursor();
Capture("\n",1);
}
}
}
/* DoTab():
*
* Special function: handle tab, move cursor to next
* tab stop.
*/
VOID
DoTab()
{
WORD Column;
if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
Column = LastColumn;
else
Column = ((LastColumn + 1) / 2) - 1;
ClearCursor();
if(Config . AutoWrap)
{
if(CursorX >= LastColumn)
{
CursorX = 0;
DownLine();
}
else
{
while(CursorX < Column)
{
CursorX++;
if(TabStops[CursorX])
break;
}
}
}
else
{
while(CursorX < Column)
{
CursorX++;
if(TabStops[CursorX])
break;
}
}
SetCursor();
Capture("\t",1);
}
/* DoEnq():
*
* Special function: send answerback message.
*/
VOID
DoEnq()
{
if(Config . AnswerBack[0])
SerialCommand(Config . AnswerBack);
}
/* GfxText(struct RastPort *RPort,STRPTR Buffer,LONG Length):
*
* Text output, if necessary switching from gfx font
* to current default font.
*/
VOID __regargs
GfxText(struct RastPort *RPort,STRPTR Buffer,LONG Length)
{
BYTE Mode = 1;
while(Length--)
{
if(GfxTable[*Buffer] == Mode)
Text(RPort,Buffer++,1);
else
{
if(Mode)
{
if(Config . Font == FONT_IBM && IBM)
SetFont(RPort,IBM);
else
SetFont(RPort,Topaz);
}
else
SetFont(RPort,GFX);
Mode ^= 1;
Text(RPort,Buffer++,1);
}
}
if(!Mode)
SetFont(RPort,GFX);
}
/* SpillTheBeans(UBYTE *Buffer,LONG Size):
*
* Output a buffer of given size to the terminal
* window.
*/
STATIC VOID __regargs
SpillTheBeans(UBYTE *Buffer,LONG Size)
{
if(ControllerActive)
{
if(Size)
{
if(!FWrite(PrinterCapture,Buffer,Size,1))
{
BlockWindows();
if(!MyEasyRequest(NULL,LocaleString(MSG_CONSOLE_ERROR_WRITING_TO_PRINTER_TXT),LocaleString(MSG_CONSOLE_IGNORE_CLOSE_PRINTER_TXT)))
ClosePrinterCapture(TRUE);
ReleaseWindows();
}
}
}
else
{
UBYTE Scale,CharScale;
WORD Offset,LastChar;
/* Reposition the cursor and turn it off. */
ClearCursor();
Scale = RasterAttr[CursorY];
if(Config . FontScale == SCALE_HALF)
{
switch(Scale)
{
case SCALE_ATTR_TOP2X:
case SCALE_ATTR_BOT2X:
case SCALE_ATTR_NORMAL: CharScale = TRUE;
LastChar = LastColumn;
break;
case SCALE_ATTR_2X: CharScale = FALSE;
LastChar = LastColumn;
break;
}
}
else
{
switch(Scale)
{
case SCALE_ATTR_TOP2X:
case SCALE_ATTR_BOT2X:
case SCALE_ATTR_2X: CharScale = TRUE;
LastChar = ((LastColumn + 1) / 2) - 1;
break;
case SCALE_ATTR_NORMAL: CharScale = FALSE;
LastChar = LastColumn;
break;
}
}
if(CurrentFont == GFX)
{
/* Do we still have a character in the
* magnificient buffer?
*/
while(Size)
{
/* Cursor is positioned at
* the right hand side of the
* display. If auto-wrap is
* enabled, perform some
* kind of CR/LF, else leave
* the cursor where it is and
* quit the show.
*/
if(CursorX > LastChar)
{
/* Wrap cursor. */
if(Config . AutoWrap)
{
/* Move to beginning of next line. */
CursorX = 0;
DownLine();
Capture("\n",1);
Scale = SCALE_ATTR_NORMAL;
CharScale = (Config . FontScale == SCALE_NORMAL) ? FALSE : TRUE;
LastChar = LastColumn;
/* Reposition cursor, don't redraw it. */
ClipBlitCursor(FALSE,TRUE);
}
else
{
/* Stop the cursor. */
CursorX = LastChar;
Capture(Buffer,Size);
/* Make it reappear. */
SetCursor();
return;
}
}
if(CursorX <= LastChar)
{
/* We won't have to take
* care of characters to shift.
* We'll collect as many
* characters in the buffer as will
* fit into the current line
* and print them.
*/
if((Offset = LastChar + 1 - CursorX) > Size)
{
Offset = Size;
if(Config . InsertChar)
{
RasterShiftChar(Offset);
ScrollLineShiftChar(Offset);
ShiftChar(Offset);
}
}
RasterPutString(Buffer,Offset);
ScrollLinePutString(Offset);
if(CharScale)
PrintScaled(Buffer,Offset,Scale);
else
GfxText(RPort,Buffer,Offset);
Capture(Buffer,Offset);
Buffer += Offset;
Size -= Offset;
CursorX += Offset;
}
}
}
else
{
/* Do we still have a character in the
* magnificient buffer?
*/
while(Size)
{
/* Cursor is positioned at
* the right hand side of the
* display. If auto-wrap is
* enabled, perform some
* kind of CR/LF, else leave
* the cursor where it is and
* quit the show.
*/
if(CursorX > LastChar)
{
/* Wrap cursor. */
if(Config . AutoWrap)
{
/* Move to beginning of next line. */
CursorX = 0;
DownLine();
Capture("\n",1);
Scale = SCALE_ATTR_NORMAL;
CharScale = (Config . FontScale == SCALE_NORMAL) ? FALSE : TRUE;
LastChar = LastColumn;
/* Reposition cursor, don't redraw it. */
ClipBlitCursor(FALSE,TRUE);
}
else
{
/* Stop the cursor. */
CursorX = LastChar;
Capture(Buffer,Size);
/* Make it reappear. */
SetCursor();
return;
}
}
if(CursorX <= LastChar)
{
/* We won't have to take
* care of characters to shift.
* We'll collect as many
* characters in the buffer as will
* fit into the current line
* and print them.
*/
if((Offset = LastChar + 1 - CursorX) > Size)
{
Offset = Size;
if(Config . InsertChar)
{
RasterShiftChar(Offset);
ScrollLineShiftChar(Offset);
ShiftChar(Offset);
}
}
RasterPutString(Buffer,Offset);
ScrollLinePutString(Offset);
if(CharScale)
PrintScaled(Buffer,Offset,Scale);
else
Text(RPort,Buffer,Offset);
Capture(Buffer,Offset);
Buffer += Offset;
Size -= Offset;
CursorX += Offset;
}
}
}
/* Make the cursor reappear. */
SetCursor();
}
}
/* ConWrite(APTR Buffer,LONG Size):
*
* Write a string to the console window.
*/
VOID __regargs
ConWrite(APTR Buffer,LONG Size)
{
STATIC UBYTE StringBuffer[200],BufSize = 0;
UBYTE *Char = Buffer;
/* Run down the buffer. */
while(Size--)
{
/* Are we parsing a control sequence? */
if(InSequence)
{
if(AbortTable[*Char])
{
DoCancel();
if(*Char == ESC || *Char == CSI)
InSequence = TRUE;
}
else
{
/* See if we are already done. */
InSequence = ParseCode(*Char++);
}
}
else
{
/* This looks like a control sequence
* introducing character.
*/
if(*Char == ESC || *Char == CSI)
{
if(BufSize)
{
SpillTheBeans(&StringBuffer[0],BufSize);
BufSize = 0;
}
/* So we're in TTY mode,
* escape the `escape' character
* and continue.
*/
if(Config . Emulation == EMULATION_TTY)
{
StringBuffer[BufSize++] = '^';
StringBuffer[BufSize++] = '[';
}
else
{
if(*Char == ESC)
InSequence = TRUE;
else
CSIFake();
}
Char++;
}
else
{
/* Stuff the character into
* the buffer.
*/
StringBuffer[BufSize++] = *Char++;
/* If buffer is full, spill it. */
if(BufSize == 200)
{
SpillTheBeans(&StringBuffer[0],BufSize);
BufSize = 0;
}
}
}
}
/* Any characters in the buffer we didn't process yet? */
if(!InSequence && BufSize)
{
SpillTheBeans(&StringBuffer[0],BufSize);
BufSize = 0;
}
}
/* ConProcess(UBYTE *String,LONG Size):
*
* Process the contents of a string to be sent to the
* console window.
*/
VOID __regargs
ConProcess(UBYTE *String,LONG Size)
{
LONG i;
/* If the capture filter happens to be disabled, write the
* raw data.
*/
if(!Config . CaptureFilter)
CaptureToFile(String,Size);
/* Oh dear, an external emulation will take care of
* displaying the data so we will need to make sure
* that the data flow filter and the capture streams
* are properly fed.
*/
if(XEmulatorBase && Config . Emulation == EMULATION_EXTERNAL)
{
/* Feed the flow filter... */
if(Config . StripBit8)
{
for(i = 0 ; i < Size ; i++)
FlowFilter(String[i] & 0x7F);
}
else
{
for(i = 0 ; i < Size ; i++)
FlowFilter(String[i]);
}
/* Are we to output data? */
if(!Quiet)
{
XEmulatorWrite(XEM_IO,String,Size);
/* Build another string to contain
* the pure ASCII contents, i.e.
* not including any ESC control
* sequences.
*/
if(StripBuffer)
{
XEM_HostData . Source = String;
XEM_HostData . Destination = StripBuffer;
if(i = XEmulatorHostMon(XEM_IO,&XEM_HostData,Size))
Capture(StripBuffer,i);
}
}
}
else
{
LONG j;
/* If the eighth bit is to be stripped from incoming
* characters, let's process the whole stuff
* in a different loop... (and that's all for the
* sake of speed).
*/
if(Config . StripBit8)
{
/* In quiet mode no characters are echoed to the
* console window, they are just passed through
* the data flow filter. Usually, this mode is
* enabled by the dial panel.
*/
if(Quiet)
{
for(i = 0 ; i < Size ; i++)
FlowFilter(String[i] & 0x7F);
}
else
{
UBYTE c;
/* Check which font we are in, if other than Topaz
* the only invalid char is a Null (0) which will
* display as a space if let to continue.
*/
if(Config . Font == FONT_TOPAZ)
{
for(i = 0, j = 0 ; i < Size ; i++)
{
c = String[i] & 0x7F;
FlowFilter(c);
if(IsPrintable(c))
{
/* This character is associated with a
* special function (bell, xon, xoff, etc.).
*/
if(SpecialMap[c] != -1)
{
if(j)
{
ConWrite(SharedBuffer,j);
j = 0;
}
SpecialKeys[SpecialMap[c]] . Routine();
}
else
{
/* Put the character into the buffer
* and flush it if necessary.
*/
SharedBuffer[j++] = c;
if(j == 512)
{
ConWrite(SharedBuffer,j);
j = 0;
}
}
}
}
}
else
{
for(i = 0, j = 0 ; i < Size ; i++)
{
if(c = (String[i] & 0x7F))
{
FlowFilter(c);
/* This character is associated with a
* special function (bell, xon, xoff, etc.).
*/
if(SpecialMap[c] != -1)
{
if(j)
{
ConWrite(SharedBuffer,j);
j = 0;
}
SpecialKeys[SpecialMap[c]] . Routine();
}
else
{
/* Put the character into the buffer
* and flush it if necessary.
*/
SharedBuffer[j++] = c;
if(j == 512)
{
ConWrite(SharedBuffer,j);
j = 0;
}
}
}
}
}
if(j)
ConWrite(SharedBuffer,j);
}
}
else
{
if(Quiet)
{
for(i = 0 ; i < Size ; i++)
FlowFilter(String[i]);
}
else
{
UBYTE c;
if(Config . Font == FONT_TOPAZ)
{
for(i = 0, j = 0 ; i < Size ; i++)
{
c = String[i];
FlowFilter(c);
if(IsPrintable(c))
{
if(SpecialMap[c] != -1)
{
if(j)
{
ConWrite(SharedBuffer,j);
j = 0;
}
SpecialKeys[SpecialMap[c]] . Routine();
}
else
{
SharedBuffer[j++] = c;
if(j == 512)
{
ConWrite(SharedBuffer,j);
j = 0;
}
}
}
}
}
else
{
for(i = 0, j = 0 ; i < Size ; i++)
{
if(c = String[i])
{
FlowFilter(c);
if(SpecialMap[c] != -1)
{
if(j)
{
ConWrite(SharedBuffer,j);
j = 0;
}
SpecialKeys[SpecialMap[c]] . Routine();
}
else
{
SharedBuffer[j++] = c;
if(j == 512)
{
ConWrite(SharedBuffer,j);
j = 0;
}
}
}
}
}
if(j)
ConWrite(SharedBuffer,j);
}
}
}
}
/* ConWrites(UBYTE *String,...):
*
* Output a string to the console.
*/
VOID __stdargs
ConWrites(UBYTE *String,...)
{
va_list VarArgs;
va_start(VarArgs,String);
VSPrintf(SharedBuffer,String,VarArgs);
va_end(VarArgs);
ConProcess(SharedBuffer,strlen(SharedBuffer));
}
/* KeyConvert(struct IntuiMessage *Massage,UBYTE *Buffer):
*
* Convert a raw key information according to the
* current keymap settings.
*/
UBYTE __regargs
KeyConvert(struct IntuiMessage *Massage,UBYTE *Buffer,LONG *Len)
{
if(Buffer)
Buffer[0] = 0;
if(Len)
*Len = 0;
if(Massage -> Class == IDCMP_RAWKEY)
{
/* These are the sequences mapped to special
* control keys (cursor keys, function keys,
* the help key).
*/
STATIC struct
{
UBYTE *RawCode;
UBYTE Result;
} ConversionTable[16] =
{
(UBYTE *)"A", CUP,
(UBYTE *)"B", CDN,
(UBYTE *)"C", CFW,
(UBYTE *)"D", CBK,
(UBYTE *)"?~", HLP,
(UBYTE *)"0~", FN1,
(UBYTE *)"1~", FN2,
(UBYTE *)"2~", FN3,
(UBYTE *)"3~", FN4,
(UBYTE *)"4~", FN5,
(UBYTE *)"5~", FN6,
(UBYTE *)"6~", FN7,
(UBYTE *)"7~", FN8,
(UBYTE *)"8~", FN9,
(UBYTE *)"9~", F10
};
STATIC UBYTE SeqLens[16] = {1,1,1,1,2,2,2,2,2,2,2,2,2,2,2 };
/* Key was pressed, not released. */
if(!(Massage -> Code & IECODE_UP_PREFIX))
{
UBYTE ConvertBuffer[257],i;
ULONG Qualifier = Massage -> Qualifier;
LONG Actual;
/* If it's a function key clear the qualifier. */
if(Massage -> Code >= 80 && Massage -> Code <= 89)
Qualifier = NULL;
/* Convert the key. */
FakeInputEvent -> ie_Code = Massage -> Code;
FakeInputEvent -> ie_Qualifier = Qualifier;
FakeInputEvent -> ie_position . ie_addr = *((APTR *)Massage -> IAddress);
if((Actual = RawKeyConvert(FakeInputEvent,(UBYTE *)ConvertBuffer,256,KeyMap)) > 0)
{
if(ConvertBuffer[0])
{
if(Config . SwapBSDelete)
{
for(i = 0 ; i < Actual ; i++)
{
if(ConvertBuffer[i] == BKS)
ConvertBuffer[i] = DEL;
else
{
if(ConvertBuffer[i] == DEL)
ConvertBuffer[i] = BKS;
}
}
}
if(Len)
{
if(Actual == 1 && (Qualifier & IEQUALIFIER_CONTROL))
{
if(ConvertBuffer[0] == '@' || ConvertBuffer[0] == ' ')
{
ConvertBuffer[0] = Buffer[0] = 0;
*Len = 1;
}
else
{
*Len = Actual;
if(Buffer)
memcpy(Buffer,ConvertBuffer,Actual);
}
}
else
{
*Len = Actual;
memcpy(Buffer,ConvertBuffer,Actual);
}
}
else
{
if(Buffer)
memcpy(Buffer,ConvertBuffer,Actual);
}
/* Translated sequence starts
* with a CSI, let's have a look
* at the associated control
* key.
*/
if(ConvertBuffer[0] == CSI)
{
for(i = 0 ; i < sizeof(SeqLens) ; i++)
{
if(!Strnicmp(&ConvertBuffer[1],ConversionTable[i] . RawCode,SeqLens[i]))
{
ConvertBuffer[0] = ConversionTable[i] . Result;
if(Buffer)
{
Buffer[0] = ConversionTable[i] . Result;
Buffer[1] = 0;
if(Len)
*Len = 1;
}
break;
}
}
}
return(ConvertBuffer[0]);
}
}
/* If nothing came from the key conversion,
* check for shift-tab.
*/
if(Massage -> Code == 66 && (Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)))
{
*Len = 2;
strcpy(ConvertBuffer,"\33\t");
if(Buffer)
memcpy(Buffer,ConvertBuffer,2);
return(ConvertBuffer[0]);
}
}
}
return(0);
}